using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using Styx;
using Styx.Common;
using Styx.Helpers;
using Styx.WoWInternals;

namespace Talented.Forms
{
    public partial class FormConfig : Form
    {
        public FormConfig()
        {
            InitializeComponent();
        }
        
        private void FormConfig_Load(object sender, EventArgs e)
        {
            btnRefresh.Click += (s,args) => RefreshTalentBuilds();
            btnSaveAndClose.Click += (s, args) =>
                                         {
                                             TalentedSettings.Instance.Save();
                                             Close();
                                         };
            RefreshTalentBuilds();
        }

        private List<TalentTree> _talentBuilds = new List<TalentTree>();

        private void RefreshTalentBuilds()
        {
            lbTalentBuilds.Items.Clear();
            _talentBuilds.Clear();


            var dataDirectory = Path.Combine(Utilities.AssemblyDirectory, "Data");
            var talentBuildPath = Path.Combine(dataDirectory, "Talent Builds");
            string[] files = Directory.GetFiles(talentBuildPath, "*.xml", SearchOption.AllDirectories);

            for (int i = 0; i < files.Length; i++)
            {
                string file = files[i];
                
                try
                {
                    TalentTree talentTree = TalentTree.FromXml(XElement.Load(file));

                    _talentBuilds.Add(talentTree);
                }
                catch (XmlException ex)
                {
                    Logging.Write("[Talented]: Could not load talent build {0}", ex.Message);
                }
            }

            _talentBuilds = _talentBuilds.OrderBy(t => t.Class.ToString()).ThenBy(t => t.Specialization).ThenBy(t => t.BuildName).ToList();
            lbTalentBuilds.Items.AddRange(_talentBuilds.ToArray());

            if (!string.IsNullOrEmpty(TalentedSettings.Instance.ChoosenTalentBuildName))
            {
                var build =
                    _talentBuilds.FirstOrDefault(b => b.BuildName == TalentedSettings.Instance.ChoosenTalentBuildName);

                if (build != null)
                    lbTalentBuilds.SelectedIndex = _talentBuilds.IndexOf(build);
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (lbTalentBuilds.SelectedIndex < 0 || lbTalentBuilds.SelectedIndex >= _talentBuilds.Count)
            {
                Close();
                return;
            }

            var selectedBuild = _talentBuilds[lbTalentBuilds.SelectedIndex];

            TalentedSettings.Instance.ChoosenTalentBuildName = selectedBuild.BuildName;
            TalentedSettings.Instance.ChoosenTalentClass = selectedBuild.Class;
            Close();
        }

        private void lbTalentBuilds_SelectedIndexChanged(object sender, EventArgs e)
        {
            lbTalents.Items.Clear();

            var item = lbTalentBuilds.SelectedItem;
            if(item is TalentTree)
            {
                var talentTree = (TalentTree) item;
                lblClass.Text = "Class: " + talentTree.Class;
                lblName.Text = "Name: " + talentTree.BuildName;

                foreach(TalentPlacement tp in talentTree.TalentPlacements)
                    lbTalents.Items.Add(tp);
            }
        }

        private void btnDump_Click(object sender, EventArgs e)
        {
            var talents = BuildLearnedTalents();

            XElement rootElement = new XElement("TalentTree",
                                                new XAttribute("Name", "Name of this build"),
                                                new XAttribute("Specialization", Lua.GetReturnVal<int>("return GetSpecialization()", 0)),
                                                new XAttribute("Class", StyxWoW.Me.Class));

            foreach(TalentPlacement tp in talents)
                rootElement.Add(
                    new XElement("Talent",
                        new XAttribute("Tier", tp.Tier),
                        new XAttribute("Index", tp.Index),
                        new XAttribute("Name", tp.Name))
                    );
            
            Clipboard.SetText(rootElement.ToString());
            MessageBox.Show(
                "Xml of current build dumped to clipboard!", 
                "Sucess!", 
                MessageBoxButtons.OK,
                MessageBoxIcon.Information
                );
        }

        private static IEnumerable<TalentPlacement> BuildLearnedTalents()
        {
            var ret = new List<TalentPlacement>();

            using (StyxWoW.Memory.AcquireFrame())
            {
                for (int tierIndex = 0; tierIndex < 6; tierIndex++)
                {
                    for (int talentIndex = 1; talentIndex <= 3; talentIndex++)
                    {
                        var index = tierIndex*3 + talentIndex;
                        var vals = Lua.GetReturnValues("return GetTalentInfo(" + index + ")");
                        var name = vals[0];
                        var learned = int.Parse(vals[4]) != 0;

                        if (learned)
                        {
                            ret.Add(new TalentPlacement(tierIndex + 1, talentIndex, name));
                        }
                    }
                }
            }

            return ret;
        }
    }
}
